<template>
  <div class="screen-preview-wrap">
    <div class="header">
      <div class="title-wrap" @click="openMenu">
        <i class="iconfont icon-zonglan1"></i>
        <span class="title">{{ menuName }}</span>
      </div>
    </div>
    <div class="body" v-loading="isLoading">
      <div :class="['menu', isMenu ? 'menu-show' : 'menu-hidden']">
        <el-menu
          class="cover-menu"
          mode="vertical"
          :unique-opened="true"
          :default-active="defaultActive"
          @select="(v) => menuChange(v, true)"
        >
          <template v-for="item in menuTree">
            <el-menu-item v-if="item.leaf" :index="item.id">
              <common-carousel-text :content="item.name"></common-carousel-text>
            </el-menu-item>

            <el-submenu
              v-if="!item.leaf && item.children && item.children.length"
              :index="item.id"
            >
              <template slot="title">
                <common-carousel-text :content="item.name">
                </common-carousel-text>
              </template>
              <el-menu-item
                class="cover-menu-item"
                v-for="(d, i) in item.children"
                :key="i"
                :index="d.id"
              >
                <common-carousel-text :content="d.name"></common-carousel-text>
              </el-menu-item>
            </el-submenu>
          </template>
        </el-menu>
      </div>
      <transition name="mark" mode="out-in">
        <div v-if="isMenu" class="mark" @click="closeMenu"></div>
      </transition>

      <div class="screen-container">
        <gridEchart
          ref="gridEchart"
          :draggable="false"
          :resizable="false"
          :del="false"
          :boxList="boxList"
        />
      </div>
    </div>
  </div>
</template>

<script>
import {
  report_tree,
  report_getComponent,
  report_getReport,
} from "@/api/management/echart/report-config";

import gridEchart from "@/components/gridEchart";
import BaseList from "@/mixins/BaseList";
import { formatDate } from "@/utils";

export default {
  name: "",
  mixins: [BaseList],
  components: { gridEchart },
  props: {},
  data() {
    return {
      isMenu: false,
      menuName: "",
      menuTree: [],
      instance: null,
      timeout: undefined,
      selectMenu: null,
      boxList: [],
      period: null, // 时间周期
      isLoading: false,
      defaultActive: "0",
    };
  },
  methods: {
    /**
     *
     * @param period 周期 分钟
     */
    handleInterval(period) {
      this.clearInstance();

      if (period) {
        console.group("初始化定时调度");
        console.log("起始于: ", formatDate(new Date().getTime()));
        console.log(`周期: ${period * 60}秒`);
        console.groupEnd();

        this.instance = setInterval(() => {
          console.log("执行定时器: ", formatDate(new Date().getTime()));
          this.handleData();
        }, period * 60 * 1000);
      }
    },
    clearInstance() {
      if (this.instance) {
        clearInterval(this.instance);
        this.instance = null;
      }
    },
    menuChange(v) {
      this.defaultActive = v;
      this.boxList = [];
      this.isLoading = true;
      report_getReport({ id: v })
        .then((res) => {
          if (res && res.code === 200) {
            this.period = res.timeinterval;
            this.menuName = res.name;

            this.handleInterval(res.frequency);

            this.boxList = res.data.reduce((r, c, i) => {
              r.push({
                key: `${c.componentId}_${i}`,
                name: "",
                x: c.x,
                y: c.y,
                w: c.w,
                h: c.h,
                i: c.componentId,
                isLoading: true,
                option: null,
              });
              return r;
            }, []);

            this.handleData();
          }
        })
        .finally(() => {
          this.isLoading = false;
        });
    },
    getTree() {
      report_tree({}).then((res) => {
        this.menuTree = res.data[0].children;

        if (
          this.menuTree &&
          this.menuTree instanceof Array &&
          this.menuTree.length
        ) {
          let firstMenu = this.menuTree.find((menu) => {
            if (menu.leaf) {
              return true;
            } else {
              return !!(menu.children && menu.children.length);
            }
          });

          if (firstMenu) {
            if (firstMenu.leaf) {
              this.menuChange(firstMenu.id);
            } else {
              this.menuChange(firstMenu.children[0].id);
            }
          }
        }
      });
    },
    handleData() {
      this.boxList.forEach((item) => {
        this.getChartData(item.i).then(({ opt, name }) => {
          item.option = opt;
          item.name = name;
          item.isLoading = false;
          item.key = `${item.i}_${new Date().getTime()}`;
        });
      });
    },
    handleOption(list, option, mapper) {
      option.dataset = {
        dimensions: mapper.dimensions.split(","),
        source: list,
      };
      return option;
    },
    getChartData(id) {
      return new Promise((resolve, reject) => {
        report_getComponent({
          componentId: id,
          timeinterval: this.period,
        }).then((res) => {
          if (res && res.code === 200) {
            let option, mapper;
            let { name } = res.component;
            let { list } = res.data;

            let configStr = res.component.parameter;
            let optionStr = res.component.echart.parameter;

            try {
              let config = JSON.parse(configStr);
              mapper = config.mapper;
            } catch (e) {
              console.err("配置项转换异常: ", e);
            }

            try {
              option = JSON.parse(optionStr);
            } catch (e) {
              console.err("option转换异常: ", e);
            }

            if (list && option && mapper) {
              let fullOption = this.handleOption(list, option, mapper);
              resolve({
                opt: fullOption,
                name,
              });
            } else {
              reject();
            }
          } else {
            reject();
          }
        });
      });
    },
    openMenu() {
      this.isMenu = !this.isMenu;
    },
    closeMenu() {
      if (this.isMenu) this.isMenu = false;
    },
  },
  created() {},
  mounted() {
    this.getTree();
  },
  beforeDestroy() {
    this.clearInstance();
  },
};
</script>
<style lang="scss" scoped>
.container {
  .left-box {
    ::v-deep {
      .el-menu {
        .el-menu-item {
          height: 38px;
          line-height: 38px;

          &.is-active {
            color: #fff !important;
            background-color: #002140 !important;

            &::before {
              content: "";
              position: absolute;
              left: 0;
              top: 0;
              bottom: 0;
              width: 4px;
              background-color: #0c74d5;
            }
          }
        }
      }
    }
  }

  .right-box {
    margin-left: 207px;
    height: 100%;
    background-color: #fff;

    .grid-box {
      height: 100%;
      width: 100%;
    }
  }
}

.screen-preview-wrap {
  width: 100%;
  height: 100%;
  background-color: #fff;

  .header {
    height: 49px;
    width: 100%;
    border-bottom: 1px solid #eee;
    display: flex;
    align-items: center;
    padding: 0 12px;

    .title-wrap {
      color: #303133;
      cursor: pointer;
      user-select: none;

      .title {
        margin-left: 4px;
      }
    }
  }

  .body {
    height: calc(100% - 50px);
    width: 100%;
    position: relative;
    overflow-x: hidden;

    .menu {
      width: 200px;
      height: 100%;
      overflow-y: scroll;
      overflow-x: hidden;
      position: absolute;
      top: 0;
      transition: left 0.15s linear;
      background-color: #fff;
      z-index: 3;
    }

    .menu-show {
      left: 0;
    }

    .menu-hidden {
      left: -200px;
    }

    .cover-menu {
      height: 100%;
      width: 100%;
      border-right: 0 !important;
      user-select: none;

      ::v-deep .el-submenu__title {
        display: flex;
        align-items: center;

        .carousel-text-warp {
          width: calc(100% - 24px);
        }
      }
      .cover-menu-item {
        display: flex;
        align-items: center;
      }
      .el-menu-item {
        display: flex;
        align-items: center;
      }

      ::v-deep .carousel-name-info-show,
      ::v-deep .basic-name-item {
        vertical-align: baseline !important;
      }
    }

    .mark {
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      background-color: #000;
      opacity: 0.5;
      z-index: 2;
    }

    .mark-enter-active,
    .mark-leave-active {
      transition: opacity 0.15s linear;
    }

    .mark-enter,
    .fade-leave-to {
      opacity: 0;
    }

    .screen-container {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
